#include "propertymodel.hpp"

PropertyModel::PropertyModel(QObject *parent)
    : QAbstractItemModel(parent)
{
//    rootItem = new PropertyItem(Q_NULLPTR);
}

PropertyModel::~PropertyModel()
{
    qDeleteAll(rootItem);
    rootItem.clear ();
}

bool PropertyModel::buildModelByArgs(QStringList names, QStringList argvs)
{
    qDeleteAll(rootItem);
    rootItem.clear ();

    for(int i=0;i<argvs.count ();i++)
    {
        PropertyItem *Item = new PropertyItem(Q_NULLPTR);
        Item->setBuildItemsByDBusArg (argvs.at (i));
        if(i<names.count ()>i)
        {
            Item->setName (names.at (i));
        }
        rootItem.append (Item);
    }
    return true;
}

QVariant PropertyModel::headerData(int section, Qt::Orientation orientation, int role) const
{
    // FIXME: Implement me!
    if (role != Qt::DisplayRole)
        return QVariant();
    return section;
}

bool PropertyModel::setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role)
{
    if (value != headerData(section, orientation, role)) {
        // FIXME: Implement me!
        emit headerDataChanged(orientation, section, section);
        return true;
    }
    return false;
}

QModelIndex PropertyModel::index(int row, int column, const QModelIndex &parent) const
{
    // FIXME: Implement me!

    if (!parent.isValid())
    {
        PropertyItem *Item = rootItem.at (row);
        return createIndex(row,column,Item);
    }

    PropertyItem *parentItem;
    parentItem = static_cast<PropertyItem*>(parent.internalPointer());

    PropertyItem *childItem = parentItem->getChildItem(row);
    if (childItem)
        return createIndex(row, column, childItem);
    else
        return QModelIndex();
}

QModelIndex PropertyModel::parent(const QModelIndex &index) const
{
    // FIXME: Implement me!
    if (!index.isValid())
        return QModelIndex();

    PropertyItem *childItem = static_cast<PropertyItem*>(index.internalPointer());
    PropertyItem *parentItem = childItem->getParent();
    if(rootItem.contains (parentItem))
    {
        int row = rootItem.indexOf (childItem);
        return createIndex(row,index.column (),parentItem);
    }
    return createIndex(parentItem->row(), 0, parentItem);
}

int PropertyModel::rowCount(const QModelIndex &parent) const
{
    if (!parent.isValid())
    {
        return rootItem.count ();
    }

    // FIXME: Implement me!

    PropertyItem *parentItem;
    parentItem = static_cast<PropertyItem*>(parent.internalPointer());

    return parentItem->childCount();

}

int PropertyModel::columnCount(const QModelIndex &parent) const
{

    // FIXME: Implement me!
    return 4;
}

bool PropertyModel::hasChildren(const QModelIndex &parent) const
{
    // FIXME: Implement me!
    return QAbstractItemModel::hasChildren (parent);

}

bool PropertyModel::canFetchMore(const QModelIndex &parent) const
{
    // FIXME: Implement me!
    return QAbstractItemModel::canFetchMore (parent);
}

void PropertyModel::fetchMore(const QModelIndex &parent)
{
    // FIXME: Implement me!
    return QAbstractItemModel::fetchMore (parent);
}

QVariant PropertyModel::data(const QModelIndex &index, int role) const
{
    if (!index.isValid())
        return QVariant();

    // FIXME: Implement me!
    if (role == Qt::CheckStateRole)
    {
        PropertyItem *item = static_cast<PropertyItem*>(index.internalPointer());
        DVariant d = item->getValue ();
        if(d.type () == QMetaType::Bool)
        {
            return d.getBool ()?Qt::Unchecked: Qt::Checked ;
        }
        return QVariant();
    }

    if (role != Qt::DisplayRole)
        return QVariant();

    PropertyItem *item = static_cast<PropertyItem*>(index.internalPointer());

    return item->data(index.column());

    return QVariant();
}

bool PropertyModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
    if (!index.isValid())
        return false;

    // FIXME: Implement me!
    if (role == Qt::CheckStateRole)
    {
        PropertyItem *item = static_cast<PropertyItem*>(index.internalPointer());
        DVariant d = item->getValue ();
        if(d.type () == QMetaType::Bool)
        {
            return d.getBool ()?Qt::Unchecked: Qt::Checked ;
        }
        return false;
    }
    if (role != Qt::DisplayRole)
        return QAbstractItemModel::setData(index,value,role);

    if (data(index, role) != value) {
        // FIXME: Implement me!
        PropertyItem *item = static_cast<PropertyItem*>(index.internalPointer());
        if(item->checkDictKey (value.toString ()))
        {
            item->setValues (value.toString ());
            emit dataChanged(index, index, QVector<int>() << role);
            QModelIndex parent = index.parent ();
            while (parent.isValid()) {
                emit dataChanged(parent, parent, QVector<int>() << role);
                parent = parent.parent ();
            }
        }
        return true;
    }
    return false;
}

Qt::ItemFlags PropertyModel::flags(const QModelIndex &index) const
{
    if (!index.isValid())
        return Qt::NoItemFlags;

    if(index.column ()>1)
    {

        PropertyItem *item = static_cast<PropertyItem*>(index.internalPointer());
        if(item->isBaseType())
        {
            Qt::ItemFlags flags = Qt::ItemIsUserCheckable | QAbstractItemModel::flags(index);
            return flags;
        }

    }
    return QAbstractItemModel::flags(index);
}

bool PropertyModel::insertRows(int row, int count, const QModelIndex &parent)
{
    beginInsertRows(parent, row, row + count - 1);
    // FIXME: Implement me!
    endInsertRows();
    return true;
}

bool PropertyModel::insertColumns(int column, int count, const QModelIndex &parent)
{
    beginInsertColumns(parent, column, column + count - 1);
    // FIXME: Implement me!
    endInsertColumns();
    return true;
}

bool PropertyModel::removeRows(int row, int count, const QModelIndex &parent)
{
    beginRemoveRows(parent, row, row + count - 1);
    // FIXME: Implement me!
    endRemoveRows();
    return true;
}

bool PropertyModel::removeColumns(int column, int count, const QModelIndex &parent)
{
    beginRemoveColumns(parent, column, column + count - 1);
    // FIXME: Implement me!
    endRemoveColumns();
    return true;
}
